from tkinter import messagebox

from prompt_toolkit.keys import Keys
from pyparsing import unicode

import myfuncBPH
import cv2
import numpy as np
import os #获得 dir
import math
from tkinter import *
import tkinter.filedialog
import tkinter.messagebox #这个是消息框，对话框的关键
from PIL import Image# BW 扩展 ，防止  H/W>2 ,右侧出现 轮廓检测 丢失。
import math
#socket
import socket
import threading
import time
import sys
# end socket


#
#s02  original img
#s03  255 single image
#s05  BW image
#s10

#s15  getShape8b() BPH_angle_operated:
#s22  LFsubImg

#s24  LF img  ,before little rotate ,
#s25  shift_right_down ,prepare for little rotete
#s26  print angle , sum
#s27  adjusted img,little rotated"

#s29  img///in getshape func now",
#s30  LF part

#s39  dsetroyAllWindows  in main end .

def  testStandingLying(mywidth,myheight,here_angle,count_in_BPH):
     if   min(mywidth, myheight) < 8  and count_in_BPH>12:  #small noise size, 8,9, 10
         return "no_too small"

     if min(mywidth,myheight)>0:
         if  max(mywidth,myheight)/min(mywidth,myheight)<1.35:
             return "no_like square"

     if mywidth < myheight:
         if here_angle>70:
             return "lying"
         elif here_angle<20:
             return "standing"
         else:
             return "no_angle not >70 or <20"
     else:
         if here_angle > 70:
             return "standing"
         elif here_angle < 20:
             return "lying"
         else:
             return "no_angle not >70 or <20"

def  testLying(mywidth,myheight,here_angle):
     if mywidth < myheight:
         if here_angle>45:
               # lying = lying + 1
             lying=True
         else:
               # standing = standing + 1
             lying=False
     else:
         if here_angle > 45:
                #standing = standing + 1
             lying = False
         else:
                #lying = lying + 1
             lying=True
     return lying
def int_to_str(int_num):
    lst = []
    s = ''
    while int_num > 0:
        num = int_num % 10
        lst.append(num)
        int_num //= 10

    for i in lst[::-1]:
        s += str(i)

    return s


def FillHole(im_in):


    # 复制 im_in 图像
    im_floodfill = im_in.copy()

    # Mask 用于 floodFill，官方要求长宽+2
    h, w = im_in.shape[:2]
    mask = np.zeros((h + 2, w + 2), np.uint8)

    # floodFill函数中的seedPoint必须是背景
    isbreak = False
    for i in range(im_floodfill.shape[0]):
        for j in range(im_floodfill.shape[1]):
            if (im_floodfill[i][j] == 0):
                seedPoint = (i, j)
                isbreak = True
                break
        if (isbreak):
            break
    # 得到im_floodfill
    cv2.floodFill(im_floodfill, mask, seedPoint, 255);

    # 得到im_floodfill的逆im_floodfill_inv
    im_floodfill_inv = cv2.bitwise_not(im_floodfill)
    # 把im_in、im_floodfill_inv这两幅图像结合起来得到前景
    im_out = im_in | im_floodfill_inv
    return im_out

def getMaxContourImg(image):
    contours, hierarchy = cv2.findContours(image,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    contours = sorted(contours,key=lambda item:cv2.contourArea(item))
    x,y,w,h=cv2.boundingRect(contours[-1])  #???????? not minAreaRect ,but  just statstic state ,正姿态rect ?
    subImg =  image[y:y+h,x:x+w]
    return subImg

# refineRoi call   this  func,get LF image,   input  is large image ,return little image!!!!!???????
# no rotate !!!
def getRoiImage(image): #here image is one BPH image??, after   cv2.minAreaRect ->  crop_minAreaRect   rotate ,it is as large as  total pic  .
    contours, hierarchy = cv2.findContours(image,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #
    contours = sorted(contours,key=lambda item:cv2.contourArea(item)) #all lines in  one  BPH,

    mask = np.zeros(image.shape,np.uint8)  # mask  ,as large  as image,,,,返回来一个给定形状和类型的用0填充的数组；
    cv2.drawContours(mask,[contours[-1]],-1,255,cv2.FILLED)  #
    #cv2.imshow("mask img", mask)
    #cv2.waitKey(0)
    kernel = np.ones((3,3), np.uint8)
    mask = cv2.erode(mask,kernel)    # filter

    x,y,w,h=cv2.boundingRect(contours[-1])  #在python中，数组的下标为-1代表数组的最后一个元素，下标为-2代表数组的倒数第二个元素，......。  ###  here   largest area  mean LF?
    ROI =  mask[y:y+h,x:x+w]   #large image become little image!!!!!?????
    return ROI

#only LF test  call  this func
def refineRoi(image):      #here image is LFimage, after   cv2.minAreaRect ->  crop_minAreaRect  , rotate_clock_direct   degree maybe happen!!!???      ,it is  large ,  most is blank , little  is LF  .
    #roiImage=image  ????
    roiImage=getRoiImage(image)  #???   # get LF rect ,  not  as large as total pic   ,,roiImage very little pic !!!!
    #cv2.imshow("input img", image)  #large
    ##cv2.waitKey(0)
    cv2.imshow("LF img,,,before adjust", roiImage)   #s24
    #cv2.waitKey(0)
    #roiImage = (image)
    center= (int(roiImage.shape[0]/2),int(roiImage.shape[1]/2))  #,roiImage very little pic !!!!     shape[0]  heigth  shape[1]  width

    targetShape = (roiImage.shape[0]*10,roiImage.shape[1]*10)    #dest size  (rows,cols))
    #targetShape = (roiImage.shape[0]*8 , roiImage.shape[1]*8 )

    hmax = max(int(roiImage.shape[0] / 2), int(roiImage.shape[1] / 2)) * 1.5  # 1.414
    center = (hmax, hmax)
    targetShape =(int(2.3*hmax), int(2.3*hmax))   #


    # 声明变换矩阵 向右平移10个像素， 向下平移30个像素
    #M = np.float32([[1, 0, 10], [0, 1, 30]])
    # 进行2D 仿射变换
    if roiImage.shape[0]>roiImage.shape[1]:  #veritical
        M = np.float32([[1, 0, int(hmax),], [0, 1, 0]])
        LF_looks_x_or_y="y"
        my_axis=0
    else:                                   #horizenal
        M = np.float32([[1, 0, 0], [0, 1, int(hmax)]])
        LF_looks_x_or_y="x"
        my_axis = 1
    shifted = cv2.warpAffine(roiImage, M, targetShape)
    cv2.imshow('shift_right_down ,prrepare for little rotete', shifted)   #s25
    ##cv2.waitKey(0)
##
    maxSum=0
    index=-1

    for i in range(180):#(90):           #    0  to 90 degree
        M = cv2.getRotationMatrix2D(center, -i, 1.0) #15   M matrix is unit ,   #getRotationMatrix2D(Point2f center, double angle, double scale)
        rotated = cv2.warpAffine(shifted, M, targetShape) #16 仿射变换  ,LF rotated, #### cv2.warpAffine(img,M,(rows,cols))
           #### cv2.warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None) --> dst

        '''
        if i%10==0:
            cv2.imshow("rotate img"+str(i), rotated)  #large
            cv2.waitKey(0)
            '''
        sumCols=rotated.sum(axis=my_axis)#1)      #axis=0, 表示列。axis=1, 表示行。   ##here i get sum from left to right!horrizonal sum!!!
        tmp=max(sumCols)
        if(tmp>maxSum):     # get max of maxSum_in_some_degree  ,     ,LF is most vertical or horizonal !!!  ????/
            maxSum=tmp
            index=i
        #print("maxcols",tmp, "i index",i,index)   #s26

    print("LF?? adjust angle==========================================",index)
    M = cv2.getRotationMatrix2D(center, -index, 1.0) #15    M matrix ,     #getRotationMatrix2D(Point2f center, double angle, double scale)
    #print("refineroi msg:",-index*2)
    rotatedRoi = cv2.warpAffine(roiImage, M, targetShape) #16
    rotatedRoi=getMaxContourImg(rotatedRoi)
    cv2.imshow("adjusted img,after little rotated "+str(index)+" degree", rotatedRoi)  #large   #s27
    ##cv2.waitKey(0)
    return rotatedRoi,index  # index  is  angle operate, clock direct.

# image is as large as total picture, but only one BPH appear!!!!(if reziseRATE ==1)
def getShape8b(image, BPH_angle_operated,BPHcx,BPHcy,width,height):

    cv2.imshow("getShape8b() BPH_angle_operated:"+str(BPH_angle_operated), image)  #s15
    ##cv2.waitKey(0)
    H,W=image.shape
    #image=image[int(0.03*H):int(0.97*H),int(0.03*W):int(0.97*W)]

    #contours, hierarchy = cv2.findContours(image,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    #contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    contours, hierarchy = cv2.findContours(image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)  # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!)
    num2=len(contours)
    print("in this BPH, len(contours)",num2,",H W",H,W)

    ##got BPH size:
    maxh=0
    maxw=0
    for item in contours:  # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!), here item is one line of one BPH.

        # mini Area ,!!!!   rect is more rilyable
        temp_rect = cv2.minAreaRect(item)
        temp_width = int(temp_rect[1][0])
        temp_height = int(temp_rect[1][1])
        if  temp_width >maxw:
            maxw=temp_width
        if  temp_height >maxh:
            maxh=temp_height
    ##end got BPH size, maxh maxw,
    #################erase noise
    erased=False
    href=maxh/30 # /10可以，/15   20  30 可以
    #####if href>penWidth???
    print(maxh,maxw,href)
    for item in contours:  # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!), here item is one line of one BPH.
        # get the rect image, test and erase ,H h n u  N -> ||
        (x, y, w, h) = cv2.boundingRect(item)
        if max(w,h)<maxw*7/10:# LF 不要参与erase ,防止 LF短线被误擦!!!!!!!!!!!!!!!!!!!!!!!
            (mm, nn, ss) = myfuncBPH.eraseBPHnoise(image[y:y + h, x:x + w], 1, href)
            if ss == "erased":
                erased = True
            cv2.imshow('now:after erase HhnuN', image)
        #cv2.waitKey(0)
        # end get,test
    if erased==True:#再发现一遍轮廓，
        contours, hierarchy = cv2.findContours(image, cv2.RETR_LIST,
                                               cv2.CHAIN_APPROX_SIMPLE)  # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!)
        num2 = len(contours)
        print("after erase HhnuN , in this BPH, len(contours)", num2, ",H W", H, W)

    ###################end erase


    shapeType="0"#L F
    shapeState="x_left" # b7 at x_left .
    shapecx_BPHcx=0
    shapecy_BPHcy=0
    mybitindex=0

    #prepeare  to  get pen width ,bit_size_reference
    pen_width=0
    #temp_min=[[0] for i in range(len(contours))]
    temp_min = [0] *(len(contours))  # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!)
    temp_all_height= [0] *(len(contours))
    temp_is_noise=[0] *(len(contours))
    temp_index=0

    if len(contours) < 9:  # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!)
        # 可能1像素 宽的 笔画。

        print("maybe  sub  too thin, inner, sub less than 9")
        return 1024



    for item in contours:    # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!), here item is one line of one BPH.

        # mini Area ,!!!!   rect is more rilyable
        temp_rect = cv2.minAreaRect(item)
        temp_width = int(temp_rect[1][0])
        temp_height = int(temp_rect[1][1])
        temp_min[temp_index ] = min(temp_height ,temp_width ) #min(h,w)
        temp_all_height[temp_index]=temp_height

        if  min(temp_height ,temp_width )>0:
            if max(temp_rect[1][0]/temp_rect[1][1],temp_rect[1][1]/temp_rect[1][0])<1.5:  #if  max(h/w,w/h)<1.5
            #if max(temp_width/temp_height,temp_height/temp_width)<1.5:#太接近 方块 ，就是 噪点 ，不是 笔画？？
                temp_is_noise[temp_index]=1
            else:
                temp_is_noise[temp_index] = 0
        if min(temp_height, temp_width) ==0:
            temp_is_noise[temp_index] = 1
        temp_index+=1

      #to get pen_width
    temp_index=0
    pen_width1=1
    pen_width2=1
    for iji in range (0, len(contours) ):   # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!),
        if temp_is_noise[iji]==0: #随意, 不是噪点 就可以。
             pen_width1=temp_min[iji]   #min(h,w)
             pen_width2=pen_width1

    max_height=temp_all_height[0]
    for item in contours:   # here contours ,is all lines  inner one BPH,(in image ,only one BPH appear!!!), here item is one line of one BPH.
        if temp_min[temp_index]<=pen_width1 and temp_is_noise[temp_index]==0:
            #pen_width2 倒数第二小的pen_width,在上边这行，必须小于等于，不能用小于。当8个 比特线 测试宽度 相等，可能会出错。
            #倒数第二小，希望可以过滤 一些干扰？？
            pen_width2 = pen_width1
            pen_width1=temp_min[temp_index]

        if temp_all_height[temp_index]>max_height:
            max_height=temp_all_height[temp_index]  #max_height
        temp_index+=1
    pen_width=pen_width2

    #得到 判断 是 比特线的 依据之一： 宽度小于它 ，就是 比特线，是画刷笔宽度乘以参数：大约2.5-3.5
    bit_size_width_reference = int(pen_width * 3)
    print("pen_width", pen_width, ",bit_size_width_reference", bit_size_width_reference)

    #  use  (get LF_height)    or  use max contour_height ,then get bit_size_reference比特最小高度(似乎，可以 过滤 小噪点)/
    # 注意， 用 LF突起 高度 也可 实现， 因为 带 外 整体 边界 ， 所以 暂时 不用之。暂时 用max_height得到 这些 参考。
    #bit_size_min_reference参数：0.075接近LF突起高度了，不要再小了，再小成点了。
    #bit_size_max_reference参数：0.6 就差不多要与LF接触了，不要再大了
    bit_size_min_reference=int(max_height*0.0715207)
    bit_size_max_reference = int(max_height * 0.61)
    print("bit_size_min_reference",bit_size_min_reference,",bit_size_max_reference",bit_size_max_reference)

    #bit_two_state_size_reference比特二态中间分界值
    bit_two_state_size_reference = int(max_height * 0.3389)#0.389
    print("bit_two_state_size_reference", bit_two_state_size_reference)
    #end prepare, ok


    ##########
    ##########
    #test lines in this BPH

    mybyteb_x=[([0] * 2) for i in range(8)]
    mybyteb_y = [([0] * 2) for i in range(8)]
    mem_LF_state=""

    testsuccess = "no"  #mark,,:
    itis = [(["no"]) for i in range(3200)]  # "bit"  "LF",,,,#200 ,noise count maybe more than 100, so use 200!!!!!!!  if camera is  1920 1200   , so more than 200, so use 1200!

    ##############
    print("getShape8b()  ,method of crossBand ,prepare: ")
    inCrossBandX=[(["no"]) for i in range(3200)]  # for "in" "out"
    inCrossBandY = [(["no"]) for i in range(3200)]  # for "in" "out"
    centerX=[([0]) for i in range(3200)]
    centerY = [([0]) for i in range(3200)]
    largestOneCenterX=0
    largestOneCenterY = 0
    largestH=0
    largestW = 0
    herei = 0
    for item in contours:  # here item is one line of one BPH.  maybe 11 12
        myrect = cv2.minAreaRect(item)

        centerX[herei]= int(myrect[0][0])
        centerY[herei] = int(myrect[0][1])
        mywidth = int(myrect[1][0])  # ?? width
        myheight = int(myrect[1][1])  # heigth
        #here_angle = -myrect[2]  # -90  -10...
        if  myheight > largestH:
            largestH=myheight
            largestW= mywidth
            largestOneCenterX=int(myrect[0][0])
            largestOneCenterY = int(myrect[0][1])

        herei = herei + 1
    print("contours count ===================================================" + str(len(contours)))

    herei = 0
    bandLeft= largestOneCenterX-largestW/6
    bandRight= largestOneCenterX + largestW / 6
    bandTop = largestOneCenterY - largestH / 6
    bandBottom = largestOneCenterY + largestH / 6
    xBandCount=0
    yBandCount=0
    crossBandCount=0
    or_xy_BandCount=0
    and_xy_BandCount = 0
    for item in contours:  # here item is one line of one BPH.  maybe 11 12
        if  centerX[herei]> bandLeft and  centerX[herei]< bandRight:
            inCrossBandY[herei] ="in"
            yBandCount += 1
            print("in-x band")
        if  centerY[herei]> bandTop and  centerY[herei]< bandBottom:
            inCrossBandX[herei] ="in"
            xBandCount += 1
            print("in-y band")
        if inCrossBandX[herei] == "in"  and  inCrossBandY[herei] =="in":
            and_xy_BandCount+=1
            print("in  both xy band happened")
        if inCrossBandX[herei] == "in"  or  inCrossBandY[herei] =="in":
            or_xy_BandCount+=1
            print("in  either xy band happened")
        herei = herei + 1
    print("kkkkkkkkk len(contours)=", len(contours)," xBandCount=", xBandCount, "yBandCount=" , yBandCount ,"or_xy_BandCount=",or_xy_BandCount,"and_xy_BandCount=",and_xy_BandCount,)
    #crossband prepare ok


    ########### "standing" "lying"   test :
    print("getShape8b()  ,method of  standing lying :")
    standing = 0#count
    lying = 0 #count
    LFislying = True
    theirResult= [(["no"]) for i in range(3200)]  # for "standing" "lying"            i in range(200)    i= 0 1 2 ....199

    herei=0
    for item in contours:  # here item is one line of one BPH.  maybe 11 12
        myrect = cv2.minAreaRect(item)
        mywidth = int(myrect[1][0])  # ?? width
        myheight = int(myrect[1][1])  # heigth
        here_angle=-myrect[2]  # -90  -10...

        result=testLying(mywidth,myheight,here_angle)
        r2= testStandingLying(mywidth,myheight,here_angle,len(contours))  #if len(contours) <=12  , not test thiness of line



        print("contours count ==================================================="+str(len(contours)))



        #theirResult[herei] =r2
        if r2 == "lying" and (inCrossBandY[herei] == "in"):
            theirResult[herei] =r2
        elif r2 == "standing" and (inCrossBandX[herei] == "in"):
            theirResult[herei] =r2


        #


        if r2=="lying" and (inCrossBandY[herei]=="in"):
            lying = lying + 1
        elif r2=="standing" and (inCrossBandX[herei]=="in"):
            standing = standing + 1
        #if r2!="no":
        #    print(mywidth, myheight, here_angle,standing,lying,"r2=",r2)

        print("w",mywidth, "H",myheight,"angle=", here_angle,"standingCount=",standing,"lyingCount=", lying, "r2=", r2)
        herei = herei + 1
















    ######################################
    ##  refresh   testsuccess  , standing>10  LFislying>10,, may happen!!!!!!!!!  many little  noise
    if standing==8  and lying==1:
        testsuccess="ok"
        LFislying = True
    elif standing == 1 and lying == 8:
        testsuccess = "ok"
        LFislying = False
    else:
        testsuccess="no"

    if standing == 8 and lying >1 and lying<8:
        testsuccess = "bit_ok"
        LFislying = True
    elif standing > 1 and  standing<8 and lying == 8:
        testsuccess = "bit_ok"
        LFislying = False
    elif standing == 1 and lying >8:
        testsuccess = "LF_ok"
        LFislying = False
    elif standing >8 and lying == 1:
        testsuccess = "LF_ok"
        LFislying = True
    elif min(standing,lying) ==0 or max(standing,lying)<8:
        testsuccess="fail"

    # refresh itis[]
    if  testsuccess=="ok":
        for ii in range(3200):
            if LFislying == True:
                if theirResult[ii]=="lying":
                    itis[ii]="LF"
                if theirResult[ii]=="standing":
                    itis[ii]="bit"
            if LFislying == False:
                if theirResult[ii] == "lying":
                    itis[ii] = "bit"
                if theirResult[ii] == "standing":
                    itis[ii] = "LF"
    if testsuccess == "bit_ok":  #LF still need test
        for ii in range(3200):
            if LFislying == True:
                if theirResult[ii] == "standing":
                    itis[ii] = "bit"
            if LFislying == False:
                if theirResult[ii] == "lying":
                    itis[ii] = "bit"
    if  testsuccess=="LF_ok":   #bit still need test
        for ii in range(3200):
            if LFislying == True:
                if theirResult[ii]=="lying":
                    itis[ii]="LF"
            if LFislying == False:
                if theirResult[ii] == "standing":
                    itis[ii] = "LF"

    print("zzzzzzzzzzzzzz len(contours)=", len(contours), "standing=",standing,"lying=",lying,"LFislying=",LFislying, "testsuccess=", testsuccess)
    print(itis)
    ###################
    ###################
    #go on test ,another mother ,line width test,
    print("getShape8b()  ,method of  line_width :")
    if testsuccess == "bit_ok":
        ii = 0
        for item in contours:  # here item is one line of one BPH.  maybe 11 12
            myrect = cv2.minAreaRect(item)
            mywidth = int(myrect[1][0])  # ?? width
            myheight = int(myrect[1][1])  # heigth
            myx = int(myrect[0][0])  # center x
            myy = int(myrect[0][1])  # center y
            # angle????myrect[2]
            print("w h", mywidth, myheight, "cx cy", myx, myy)
            heremin = min(mywidth, myheight)
            heremax = max(mywidth, myheight)

            print(heremin, bit_size_width_reference, "?>   ", heremax, heremin, "DIV   ?>3   ,if.. then LF found")
            if LFislying == True:
                if theirResult[ii] == "lying":
                    if  (heremin >= int(bit_size_width_reference)) and ((heremax / heremin) > 3):  # ???????heremin >= bit_size_width_reference????  = may happen when BPH is 45degree
                        itis[ii] = "LF"
            else:
                if theirResult[ii] == "standing":
                    if  (heremin >= int(bit_size_width_reference)) and ((heremax / heremin) > 3):  # ???????heremin >= bit_size_width_reference????  = may happen when BPH is 45degree
                        itis[ii] = "LF"
            ii = ii + 1
        #
        itisLFCnt=0
        for ii in range(3200):
            if itis[ii] == "LF":
                itisLFCnt=itisLFCnt+1
        #refresh testsuccess
        if  itisLFCnt==1:
            testsuccess="ok"

    elif testsuccess == "LF_ok":
        ii = 0
        for item in contours:  # here item is one line of one BPH.  maybe 11 12
            myrect = cv2.minAreaRect(item)
            mywidth = int(myrect[1][0])  # ?? width
            myheight = int(myrect[1][1])  # heigth
            myx = int(myrect[0][0])  # center x
            myy = int(myrect[0][1])  # center y
            # angle????myrect[2]
            print("w h", mywidth, myheight, "cx cy", myx, myy)
            heremin = min(mywidth, myheight)
            heremax = max(mywidth, myheight)

            print(heremin, bit_size_width_reference, "?>   ", heremax, heremin, "DIV   ?>3   ,if.. then LF found")
            if  LFislying == True:
                if theirResult[ii] == "standing":
                    if heremin <= bit_size_width_reference and heremax >= bit_size_min_reference and heremax <= bit_size_max_reference:
                        itis[ii] = "bit"
            else:
                if theirResult[ii] == "lying":
                    if heremin <= bit_size_width_reference and heremax >= bit_size_min_reference and heremax <= bit_size_max_reference:
                        itis[ii] = "bit"
            ii=ii+1
        #
        itisbitCnt = 0
        for ii in range(3200):
            if itis[ii] == "bit":
                itisbitCnt = itisbitCnt + 1
        # refresh testsuccess
        if itisbitCnt == 8:
            testsuccess = "ok"
    #end the test : line width test,

    '''
        ###################
        # go on test ,another mother ,in_crossBand  test ,
    print("getShape8b()  ,method of in_crossBand :")
    if testsuccess == "bit_ok":
        ii = 0
        for item in contours:  # here item is one line of one BPH.  maybe 11 12

            if LFislying == True:
                if theirResult[ii] == "lying":
                    if inCrossBandY[ii]=="in":
                        itis[ii] = "LF"
            else:
                if theirResult[ii] == "standing":
                    if  inCrossBandX[ii]=="in":
                        itis[ii] = "LF"
            ii = ii + 1
        #
        itisLFCnt = 0
        for ii in range(3200):
            if itis[ii] == "LF":
                itisLFCnt = itisLFCnt + 1
        # refresh testsuccess
        if itisLFCnt == 1:
            testsuccess = "ok"
            print ("in_crossBand test,do it ,ok")

    elif testsuccess == "LF_ok":
        ii = 0
        for item in contours:  # here item is one line of one BPH.  maybe 11 12

            if LFislying == True:
                if theirResult[ii] == "standing":
                    if inCrossBandX[ii]=="in":
                        itis[ii] = "bit"
            else:
                if theirResult[ii] == "lying":
                    if inCrossBandY[ii]=="in":
                        itis[ii] = "bit"
            ii = ii + 1
        #
        itisbitCnt = 0
        for ii in range(3200):
            if itis[ii] == "bit":
                itisbitCnt = itisbitCnt + 1
        # refresh testsuccess
        if itisbitCnt == 8:
            testsuccess = "ok"
            print("in_crossBand test,do it ,ok")
    #end the test :in_crossBand  test ,
    '''











    if testsuccess=="fail":
        print("find bit0-bit7 ,LF ,fail")


    ## success,    goon ,bit x y location ,LF shape
    if testsuccess == "ok":
        print("getShape8b(),successs, find bit0-bit7 ,LF ")
        mybitindex =0
        ii = 0
        for item in contours:  # here item is one line of one BPH.  maybe 11 12
            myrect = cv2.minAreaRect(item)
            mywidth = int(myrect[1][0])  # ?? width
            myheight = int(myrect[1][1])  # heigth
            myx = int(myrect[0][0])  # center x
            myy = int(myrect[0][1])  # center y
            # angle????myrect[2]
            print("w h", mywidth, myheight, "cx cy", myx, myy)
            heremin = min(mywidth, myheight)
            heremax = max(mywidth, myheight)

            # to get bit Value (prepare)
            if itis[ii]=="bit":
                print("get bit value ,bit loaction X y")
                if mybitindex < 8:
                    if heremax >= bit_two_state_size_reference:
                        # 二态系统之大感觉 态
                        mybyteb_x[mybitindex][1] = 1
                        mybyteb_y[mybitindex][1] = 1
                    if heremax < bit_two_state_size_reference:
                        # 二态系统 之 弱小感觉 态
                        mybyteb_x[mybitindex][1] = 0
                        mybyteb_y[mybitindex][1] = 0
                    mybyteb_x[mybitindex][0] = myx
                    mybyteb_y[mybitindex][0] = myy

                    print("bit index", mybitindex, "，bit value", mybyteb_x[mybitindex][1])
                    print(" ")
                mybitindex += 1
            if itis[ii] == "LF":
                print("test LF shape, LF state....")
                ##cv2.waitKey(0)
                LFrect = cv2.minAreaRect(
                    item)  # here item is one line of one BPH. (LF)  #because LF is not well like square ,minAreaRect  get the not correct angle LFrect[2]
                #  crop_minAreaRect( image ,LFrect,MYresizeRATE)   ,mean :clear other _lines of one BPH.only LF appear!!!!   image, black white total pic.
                # crop_minAreaRect include 转角 clock_direct_operate_angle (rect[2]  ) rotate!!
                # LFsubImg,_ = crop_minAreaRect(image,LFrect,2)
                LFsubImg= crop_minAreaRect(image, LFrect, 1)  # LFsubImg as large as  total pic if resizeRATE ==1,
                cv2.imshow("LFsubImg ", LFsubImg)  #s22
                ##cv2.waitKey(0)
                LF_operate_angle = -LFrect[2]  # LFrect[2]   is nagtive

                print("LF_operate_angle", LF_operate_angle)
                if (LFsubImg is not None):
                    # after crop_minAreaRect rotate, get LFsubImg , is  not correct enough!!! so  go on adjust,refineRoi :  max of max of sum vertical horizonal????????? ,adjust_angle, rotate it !

                    # now LFsubImg is equal_rect ???why,because after crop_minAreaRect ,u get it
                    LFsubImg_adjust, LF_adjust_angle_operated = refineRoi(
                        LFsubImg)  # ????什么用？ rotate ,test 0 to 180 degree ,(because LF is not well like square ,minAreaRect  get the not correct angle LFrect[2],,,so  go on ,adjust LF angle!!!!  very little ,near 0 degree or near 180
                    # now LFsubImg_adjust is smallest_rect ???why   refineRoi -> getRoiImage() ->findContours

                    print(" LF_operate_angle in minAreaRect", LF_operate_angle)
                    print("LF_adjust_angle_operated in refineRoi ", LF_adjust_angle_operated)
                    print("BPH_angle_operated", BPH_angle_operated)
                    shapeType, shapeState = get_LF_Shape(LFsubImg_adjust,pen_width)  # LFsubImg: LF line itself ,very small pic.!!!???
                    print("LF shapeType shapeState from getshape", shapeType, shapeState)
                    print("now  get the real LFstate:")
                    if LF_adjust_angle_operated > 170:  # near 180
                        if shapeState == "x_left":  # mean b7 is at left
                            shapeState = "x_right"
                        elif shapeState == "x_right":  # mean b7 is at right
                            shapeState = "x_left"
                        elif shapeState == "y_up":  # mean b7 is at up
                            shapeState = "y_down"
                        elif shapeState == "y_down":  # mean b7 is at down
                            shapeState = "y_up"

                    print("LF shapeType shapeState", shapeType, shapeState)
                    #cv2.waitKey(0)

                    if LF_operate_angle > 70:  # near 90
                        if shapeState == "x_left":  # mean b7 is at left
                            shapeState = "y_down"
                        elif shapeState == "x_right":  # mean b7 is at right
                            shapeState = "y_up"
                        elif shapeState == "y_up":  # mean b7 is at up
                            shapeState = "x_left"
                        elif shapeState == "y_down":  # mean b7 is at down
                            shapeState = "x_right"
                    mem_LF_state = shapeState   #  it  must before  " if BPH_angle_operated ....exe"
                    print("LF shapeType shapeState", shapeType, shapeState)
                    print("mem LF  shapeState", mem_LF_state)
                    # now   LFstate is saying , with the BPH_rotated  envirenment.
                    ''' no use????   
                    if BPH_angle_operated > 70:  # near      BPH_angle_operated is  when  BPH  crop....
                        if shapeState == "x_left":  # mean b7 is at left
                            shapeState = "y_down"
                        elif shapeState == "x_right":  # mean b7 is at right
                            shapeState = "y_up"
                        elif shapeState == "y_up":  # mean b7 is at up
                            shapeState = "x_left"
                        elif shapeState == "y_down":  # mean b7 is at down
                            shapeState = "x_right"
                
                    print("LF shapeType shapeState", shapeType, shapeState)
                    '''
                    LFshapex_BPHcx = LFrect[0][0] - BPHcx
                    LFshapey_BPHcy = LFrect[0][1] - BPHcy

                    print('LFshape is: ', shapeType, 'LFshapex_BPHcx', LFshapex_BPHcx, 'LFshapey_BPHcy', LFshapey_BPHcy)

            ii=ii+1
        print("bbbprepera   okokokokokkokokokokokokokokokok")

    '''
     
    '''

    #排序：(after prepare ,go on)
    #依据 x坐标 排序8个比特
    # 坐标 是 BPH rotated 后的，哦!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!shapeState 是 BPH rotated 后的!!!!
    print("now sort,////////shapeState=",shapeState, "   mem_LF_state=", mem_LF_state)
    mybyteb=[0]*8
    temp= mem_LF_state  #shapeState is  not  acurecy
    if temp == "x_left":  # mean b7 is at left
        mybyteb_x.sort()
        for bi in range(0, 8):
            mybyteb[bi] = mybyteb_x[bi][1]
    elif temp == "x_right":  # mean b7 is at right
        mybyteb_x.sort(reverse=True)
        for bi in range(0, 8):
            mybyteb[bi] = mybyteb_x[bi][1]
    elif temp == "y_up":  # mean b7 is at up
        mybyteb_y.sort()
        for bi in range(0, 8):
            mybyteb[bi] = mybyteb_y[bi][1]
    elif temp == "y_down":  # mean b7 is at down
        mybyteb_y.sort(reverse=True)
        for bi in range(0, 8):
            mybyteb[bi] = mybyteb_y[bi][1]





    print("mybyteb after sort", mybyteb, " cx-bitV  ",mybyteb_x," cy-bitV  ", mybyteb_y)

    #计算8个比特位的各个位代表值  之和，得到字节之值。
    mybytev=0
    # for ii in range(0, 8):  实际是 0 1 2 3 4 5 6 7 不带8不带最后一个 ，这个与vb不同。
    for ii in range(0, 8):
        if (mybyteb[ii]==1):
            mybytev+=2**(7-ii)
    print("mybytev:",mybytev)

    #增256：是 两个突起，像F。
    if (shapeType=='F'):
        mybytev +=256

    #若出错， 就用512表示
    if mybitindex!=8:
        mybytev=512

    return  mybytev

# for LF check, L or F   ,getShape8b call this func
def get_LF_Shape(image,penWidth):#image  is  LFimage, #not  as large as  total pic if resizeRATE ==1,!!!!!  but LF line itself ,very small pic.

    #???  if H>W  else:
    H, W = image.shape  # shape: height width channels
    print("LF:  H  W",H,W)
    #cv2.imshow("before half ", image)
    #cv2.waitKey(0)
    LFstate=""
    LFvalue=""
    '''
    ################
    image22 = image[0:H//2, :]  ##get upon part
    #cv2.imshow("upon half ", image22)
    #cv2.waitKey(0)
    contours, hierarchy = cv2.findContours(image22, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    #contours, hierarchy = cv2.findContours(image22, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    num = len(contours)
    ################
    image22 = image[H // 2:H, :]  ##get down part
    #cv2.imshow("down half ", image22)
    #cv2.waitKey(0)
    contours, hierarchy = cv2.findContours(image22, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    num2=len(contours)

    #print("LF",num)
    if(num==1)&(num2==1):
        LFvalue= "L"
    else:
        LFvalue= "F"
    ####
    '''



    cv2.imshow("img///in getshape func now,after little adjust", image) # 29
    ##cv2.waitKey(0)
    image22 = image[0:H // 2, 0:W//2]  ##get up left part
    cv2.imshow("LF part :up left", image22)       #s30
    ##cv2.waitKey(0)
    contours, hierarchy = cv2.findContours(image22, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # contours, hierarchy = cv2.findContours(image22, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    num_up_left=0
    print("up left???????????????????????????"+str(len(contours)))
    for item in contours:#  noise    ,      very little noise , maybe 4 ||||| long part of "L" "F",  handwrite, not too line_like ,  so thin part will into   the Neighbourhood  empty quarter zone.
        (x, y, w, h) = cv2.boundingRect(item)  ## 找出轮廓包围的矩形框
        print((W,H) ,penWidth,w, h)
        #if max(item.shape[0],item.shape[1]) > min(H,W)/3  and   min( w, h)> penWidth/2 :
        if max(w,h) > min(H, W) / 3 and min(w, h) > penWidth / 2:
            num_up_left +=1
            #num_up_left = len(contours)

    image22 = image[H // 2:H, 0:W // 2]  ##get down left part
    cv2.imshow("LF part :down left", image22)
    ##cv2.waitKey(0)
    contours, hierarchy = cv2.findContours(image22, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # contours, hierarchy = cv2.findContours(image22, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    num_down_left = 0
    print("down left???????????????????????????" + str(len(contours)))
    for item in contours:  # noise
        (x, y, w, h) = cv2.boundingRect(item)  ## 找出轮廓包围的矩形框
        print((W,H), penWidth, w, h)
        #if max(item.shape[0], item.shape[1]) > min(H, W) / 3   and   min( w, h)> penWidth/2  :
        if max(w, h) > min(H, W) / 3 and min(w, h) > penWidth / 2:
            num_down_left += 1
    #num_down_left = len(contours)

    image22 = image[0:H // 2, W // 2:W]  ##get up right part
    cv2.imshow("LF part :up right", image22)
    ##cv2.waitKey(0)
    contours, hierarchy = cv2.findContours(image22, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # contours, hierarchy = cv2.findContours(image22, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    num_up_right = 0
    print("up right???????????????????????????" + str(len(contours)))
    for item in contours:  # noise
        (x, y, w, h) = cv2.boundingRect(item)  ## 找出轮廓包围的矩形框
        print((W,H), penWidth, w, h)
        #if max(item.shape[0], item.shape[1]) > min(H, W) / 3   and   min( w, h)> penWidth/2  :
        if max(w, h) > min(H, W) / 3 and min(w, h) > penWidth / 2:
            num_up_right += 1
    #num_up_right = len(contours)

    image22 = image[H // 2:H, W // 2:W]  ##get down right part
    cv2.imshow("LF part :down right", image22)
    ##cv2.waitKey(0)
    contours, hierarchy = cv2.findContours(image22, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    # contours, hierarchy = cv2.findContours(image22, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    num_down_right = 0
    print("down right???????????????????????????" + str(len(contours)))
    for item in contours:  # noise
        (x, y, w, h) = cv2.boundingRect(item)  ## 找出轮廓包围的矩形框
        print((W,H), penWidth, w, h)

        #if max(item.shape[0], item.shape[1]) > min(H, W) / 3   and   min( w, h)> penWidth/2  :
        if max(w, h) > min(H, W) / 3 and min(w, h) > penWidth / 2:
            num_down_right += 1
    #num_down_right = len(contours)

    #print("ul  dl   ur  dr", num_up_left,num_down_left, num_up_right,num_down_right ,)
    #cv2.waitKey(0)
    if H < W:            #lying

        if  num_up_left+num_down_left>=2 :
            LFstate = "x_left"
        else:
            LFstate = "x_right"
    else:               #standing

        if num_up_left +num_up_right >= 2:
            LFstate = "y_up"
        else:
            LFstate = "y_down"
    #########
    if H < W:  # lying

        if num_up_left + num_down_left == 2:
            LFvalue = "L"
        elif num_up_left + num_down_left > 2:
            LFvalue = "F"
        elif num_up_right + num_down_right == 2:
            LFvalue = "L"
        elif num_up_right + num_down_right > 2:
            LFvalue = "F"
    else:  # standing

        if num_up_left + num_up_right == 2:
            LFvalue = "L"
        elif num_up_left + num_up_right > 2:
            LFvalue = "F"
        if num_down_left + num_down_right == 2:
            LFvalue = "L"
        elif num_down_left + num_down_right > 2:
            LFvalue = "F"

    #########

    print("LFvalue, LFstate:  ", LFvalue, LFstate )
    print("num_up_left,   num_up_right  ",num_up_left,    num_up_right)
    print("num_down_left, num_down_right", num_down_left ,num_down_right)
    #cv2.waitKey(0)
    return  LFvalue, LFstate

    # here imagBW is   total pic ,  rect is for one BPH(or LF)(rect:center_x center_y w h angle), if resizeRATE==1:  return is  as large as  total pic (imageBW)   , without other BPH   only this BPH appear.!!!!
    # include 转角 clock_direct_operate_angle (rect[2] ) rotate!!
def crop_minAreaRect(imageBW, rect,resizeRATE):
    #resizeRATE 用 2 ，3 ，4 ， 5,6，  7， 8..越大越慢
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    retW,retH=rect[1]   #???????H ,w
    H,W=imageBW.shape
    rectCenter = rect[0]
    angle = rect[2]#??-90  -80   -10...


    print("mask")
    mask=np.zeros(imageBW.shape,np.uint8)  # new, fill with 0
    cv2.drawContours(mask,[box],-1,255,cv2.FILLED)
    ROI = cv2.bitwise_and(imageBW,mask)  # and operate

    print("mask ok")
    #下面 转角angle (rect[2] ) ，可能，目的， 出图是：图案顺时针 转 rect[2]成 0度的样子?? angle大约等于 -45，-90 ，0
    M = cv2.getRotationMatrix2D(rectCenter, angle, 1.0)
    #截图，减少计算，提速


    #hy0= int(rect[0][1]-max(rect[1][0],rect[1][1])/2)-1
    #if hy0<0:
    #    hy0=0
    #hy1= int(rect[0][1]+max(rect[1][0],rect[1][1])/2)+1
    #
    #hx0= int(rect[0][0]-max(rect[1][0],rect[1][1])/2)-1
    #if hx0<0:
    #    hx0=0
    #hx1 = int(rect[0][0] + max(rect[1][0],rect[1][1])/2)+1


    #cv2.imshow("BWzzzz" +   str(hy0) + str(hy1) + str(hx0) + str(hx1), imageBW)
    #cv2.waitKey(0)


    #rect[1][0], rect[1][1]  H,W//////    rect[0][0], rect[0][1]  center, x y     same as (left  top)///// rect[2]  angle - singal
    thta=-rect[2]/360*2*math.pi
    outsideW=(rect[1][1])*math.cos(thta)+(rect[1][0])*math.sin(thta)
    outsideH=(rect[1][1]) * math.sin(thta) + (rect[1][0]) * math.cos(thta)
    outsideRadius=int((outsideW*outsideW+ outsideH* outsideH)**0.5 /2) # square
    """
    hy0 = int(rect[0][1] - outsideH / 2) - 1
    if hy0 < 0:
        hy0 = 0
    hy1= int(rect[0][1] + outsideH / 2) +1

    hx0 = int(rect[0][0] - outsideW / 2) - 1
    if hx0 < 0:
        hx0 = 0
    hx1 = int(rect[0][0] + outsideW / 2) + 1
    """
    hy0 = int(rect[0][1] - outsideRadius) - 1
    if hy0 < 0:
        hy0 = 0
    hy1 = int(rect[0][1] + outsideRadius) + 1

    hx0 = int(rect[0][0] - outsideRadius) - 1
    if hx0 < 0:
        hx0 = 0
    hx1 = int(rect[0][0] + outsideRadius) + 1

    #cv2.imshow("BWaaa"+str(math.cos(60))+ "W H:"+str(outsideW)+" "+str(outsideH),imageBW)
    #cv2.waitKey(0)
    #cv2.imshow("BWabbbb" + str(hy0)+" " + str(hy1) +" "+ str(hx0)+" " + str(hx1), imageBW)
    #cv2.waitKey(0)

    #lossless rotate enbalbe
    cropped = ROI[hy0:hy1, hx0:hx1] # 裁剪坐标为[y0:y1, x0:x1]     #ROI（region of interest）——感兴趣区域。
    #cv2.imshow("cropped" , cropped)
    #cv2.waitKey(0)
    #

    #ret = cv2.warpAffine(ROI, M, (H*resizeRATE,W * resizeRATE)) #这个太慢， 计算的任务太多，没必要,但是它是无损的？计算取整损耗？
    #HH=max(rect[1][0],rect[1][1])
    #WW=HH
    #M = cv2.getRotationMatrix2D((HH/2,WW/2), angle, 1.0)
    #ret = cv2.warpAffine(cropped, M, (H * resizeRATE, W * resizeRATE))#这个快，
    #return ret,0 #add90happened

    # ret = cv2.warpAffine(ROI, M, (H*resizeRATE,W * resizeRATE)) #这个太慢， 计算的任务太多，没必要,但是它是无损的？计算取整损耗？

    HH=outsideRadius*2
    WW=HH


    M = cv2.getRotationMatrix2D((outsideRadius,outsideRadius), angle, 1.0)
    ret = cv2.warpAffine(cropped, M,(HH,WW))## (HH * resizeRATE, WW * resizeRATE))#这个快，   resizeRATE?????? useless
    #cv2.imshow("ret"+str(resizeRATE), ret)
    #cv2.waitKey(0)
    return ret


def main(resizecode,imageRGB,showDialog):
    print( "opencv version ",cv2.__version__)
    #imageRGB = cv2.imread('test.jpg')




    # 放大
    if resizecode!="normal":
        size = imageRGB.shape
        h, w = size[0], size[1]
        if h*w>1000000:  #############???????????????????????????????????????????????????????????????????
            scale =0.25#0.5# 2#3
        else:
            scale=2
        new_w, new_h = int(w * scale), int(h * scale)
        imageRGB = cv2.resize(imageRGB, (new_w, new_h),interpolation=cv2.INTER_CUBIC)
        print("resize happened")
    #放大结束，没起作用？ 起作用了。


    #图片尺寸
    sp=imageRGB.shape
    print("imagesize",sp[1],"*",sp[0])
    mypicH=sp[0]
    mypicW=sp[1]

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

    # 腐蚀图像
    erodeded =cv2.erode(imageRGB, kernel)
   # eroded = cv2.erode(erodeded, kernel)
    # 显示腐蚀后的图像
    ##cv2.imshow("Eroded Image", erodeded);

    # 膨胀图像 腐蚀图像
  ################### # dilated = cv2.dilate(imageRGB, kernel)
    # 显示膨胀后的图像
   # cv2.imshow("Dilated Image", dilated);


    # 原图像
   # cv2.imshow("Origin", imageRGB)     #s02
    #cv2.waitKey(0)


    image = cv2.cvtColor(erodeded, cv2.COLOR_BGR2GRAY)
    #image = cv2.cvtColor(dilated, cv2.COLOR_BGR2GRAY)
    # image = cv2.cvtColor(imageRGB,cv2.COLOR_BGR2GRAY)
    image = 255-image

    # 图像
    cv2.imshow("255-single", image)   #s03
    # cv2.waitKey(0)


    #(100,255  软件 出图 ，笔画色彩 淡薄 ，可 试 这个，；但是 对于 软件出图 然后拍照 屏幕，却 什么 都 识别 不出。)
    # (软件出图)70,255  （软件出图 然后 拍照屏幕 ,160 255；但是 软件 出图 的 色彩 淡薄的，却容易 不识别 。)
    _, BW = cv2.threshold(image, 160, 255, cv2.THRESH_BINARY )
    #_,BW = cv2.threshold(image,160,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    #_, BW = cv2.threshold(image, 160, 255,  cv2.THRESH_OTSU)

    #BW=FillHole(BW22)
    #cv2.imshow("BW", BW)
    #cv2.waitKey(100)

    #素描图：
    imgG = cv2.GaussianBlur(image, (3, 3), 0)
    dst = cv2.Canny(imgG, 180, 180)  # 图片卷积——》th
    #BW=dst

    #素描之二
    #imgInfo = image.shape
    #height = imgInfo[0]
    #width = imgInfo[1]
    # sobel 1 算子模版 2 图片卷积 3 阈值判决
    # [1 2 1          [ 1 0 -1
    #  0 0 0            2 0 -2
    # -1 -2 -1 ]       1 0 -1 ]

    # [1 2 3 4] [a b c d] a*1+b*2+c*3+d*4 = dst

    #dst = np.zeros((height, width, 1), np.uint8)#创建
    #gray=image
    #print("okokokokok")
    #for i in range(0, height - 2):
    #    for j in range(0, width - 2):
    #        gy = gray[i, j] * 1 + gray[i, j + 1] * 2 + gray[i, j + 2] * 1 - gray[i + 2, j] * 1 - gray[
    #            i + 2, j + 1] * 2 - gray[i + 2, j + 2] * 1
    #        gx = gray[i, j] + gray[i + 1, j] * 2 + gray[i + 2, j] - gray[i, j + 2] - gray[i + 1, j + 2] * 2 - gray[
    #            i + 2, j + 2]
    #        grad = math.sqrt(gx * gx + gy * gy)
    #        if grad > 100:
    #            dst[i, j] = 0
    #        else:
    #            dst[i, j] = 255
    #BW=dst
    #print("ok12121212")


    #防止 照片太像条幅，导致画面右侧 轮廓检测 丢失 （不知为什么 ， cv2.findContours ）
    if mypicW/mypicH>2: #画面 增高
        img1=Image.fromarray(BW)
        # 创建一个新的图片对象
        newmypicH=int(mypicW/2)
        img2 = Image.new('RGB', (mypicW, newmypicH), (0, 0, 0))
        # 圈出需要复制的图片框(这里其实是复制img整个图片)
        box1 = (0, 0, mypicW, mypicH)
        # 按圈出的框复制图片
        region = img1.crop(box1)
        img2.paste(region, (0, 0))
        BW2= np.array(img2)
        BW = cv2.cvtColor(BW2, cv2.COLOR_BGR2GRAY)
        cv2.imshow("BW,height enlarge ,",BW)
        cv2.waitKey(100)
        mypicH = newmypicH
    else:
        cv2.imshow("BW", BW)  #s05
        cv2.waitKey(100)
    #BPH检测开始
    #contours, hierarchy = cv2.findContours(BW,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    contours, hierarchy = cv2.findContours(BW,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)  #here:contours is all BPH s.
    number=0
    success_bph=0
    print("total bph may be:",len(contours))
    bhp_height=0
    mycache_x_y_v_LF= [([0] * 4) for i in range(len(contours))]
    mycache_BPHheight= [([0]) for i in range(len(contours))]
    linestartmem=[0]*len(contours)
    nextlinestartmem=[0]*len(contours)

    for item in contours:              #here:contours is all BPH s.
        #最小外接矩形 cv2.minAreaRect
        rect = cv2.minAreaRect(item)  #here rect is for one BPH , width (rect[1][0]),   height=int(rect[1][1]),angle rect[2],,, center_x ,rect[0][0],  center_y rect[0][1],
        #box = cv2.boxPoints(rect)
        #box = np.int0(box)

        width=int(rect[1][0])
        height=int(rect[1][1])
        #bph_height=height#不准 可能 某行 用小BPH , 某行 用大BPH , 所以 ，下面 做 更多判断。
        cx=int(rect[0][0]) #BPHcx  BPH centrel x
        cy=int(rect[0][1]) #BPHcy  BPH centrel y
        #?????? 过滤 ，10似乎 太小 ，用 30.
        if(min(width,height)>30 and rect[1][0]<mypicH and rect[1][1]<mypicH):
            number+=1
            #cv2.drawContours(imageRGB,[box],-1,(0,0,255))
            #boundingRect=cv2.boundingRect(item)
            print('this BPH angle ============================================================== ',rect[2])
            print("this BPH xywha",rect[0][0],rect[0][1],rect[1][0],rect[1][1],rect[2])
            bwh,bww=BW.shape

            print("before call  getshape8b,the total pic :BW",bww,bwh)
            print("before call  getshape8b,this one BPH,the minAreaRect  whxy", width,height,cx,cy)
            if min(width,height)<100 :#太小的BPH，要多放大。VB画的 大约是68宽度的,
                MYresizeRATE=3
                #elif min(width,height)>200:
                #    MYresizeRATE = 6
            else:
                MYresizeRATE=2
            if min(width, height) > 1000:  #太大的BPH,不要放大了
                MYresizeRATE = 1
            #  crop_minAreaRect(BW,rect,MYresizeRATE)   ,mean :clear other BPH.!!!!  BW, black white total pic.
            # crop_minAreaRect include 转角 clock_direct_operate_angle (rect[2] or rect[2]+90) rotate!!  if minArea_rect retW<retH: +90 happened
            subImg= crop_minAreaRect(BW,rect,MYresizeRATE)   #here rect is for one BPH,    here subImg is as large as  total pic without other BPH, only this BPH appear.!!!!
            bwh2, bww2 = subImg.shape

            print("before call  getshape8b,the cleared_sub pic without other BPH , as large as  total pic :subimg w h", bww2, bwh2)
            if(subImg is not None):                             #rect[2]  is -signal
                shapetype8b = getShape8b(subImg,-rect[2],cx,cy ,width,height)  #here rect is for one BPH,     here subImg is as large as  total pic without other BPH, only this BPH appear.!!!!
                if(shapetype8b<256): #find BPH with L
                    mycache_x_y_v_LF[success_bph][0] =cx
                    mycache_x_y_v_LF[success_bph][1] = cy
                    mycache_x_y_v_LF[success_bph][2] = shapetype8b
                    mycache_x_y_v_LF[success_bph][3]=1
                    mycache_BPHheight[success_bph]=height #判断是BPH ,赋值bph_height， 这样比较准，（还 存在 问题， 若 多个 BPH不 一样高，怎么办？？？）?????????????????????????????
                    success_bph+=1
                    print("success  to get a BPH,sum=",success_bph)
                if ((shapetype8b >= 256)and (shapetype8b <512)): #find BPH with F
                    mycache_x_y_v_LF[success_bph][0] = cx
                    mycache_x_y_v_LF[success_bph][1] = cy
                    mycache_x_y_v_LF[success_bph][2] = shapetype8b-256
                    mycache_x_y_v_LF[success_bph][3] = 2
                    mycache_BPHheight[success_bph] = height  # 判断是BPH ,赋值bph_height， 这样比较准，（还 存在 问题， 若 多个 BPH不 一样高，怎么办？？？）???????????????????????????????
                    success_bph += 1
                    print("success  to get a BPH,sum=", success_bph)

                if (shapetype8b == 512):
                     print("fail  to get a BPH")
                print(" ")
                print(" ")
                    # break
    print("test: ",number," BPH sum=",success_bph)
    print(" mycache_x_y_v_LF", mycache_x_y_v_LF)





    #sort
    mycache_v = [0] * (success_bph)
    mycache_LF = [0] * (success_bph)
    print("")
    print("my sort:")
    mycache_iii= [0]* (success_bph)
    mycache_iiiiii= [0] * (success_bph)
    tempx=0
    memiii=0
    tempy=0
    hereindex = 0
    heremax_y=0

    #暂时 用第一个y乘以2 ，够大了，。
    heremin_y= mycache_x_y_v_LF[0][1]*2
    tempy=heremin_y
    #得 整体 最小y
    for iii in range(0, (success_bph)):
        if tempy> mycache_x_y_v_LF[iii][1]:
            tempy=mycache_x_y_v_LF[iii][1]
            memiii=iii
    bph_height=mycache_BPHheight[memiii]
    print("min y i have got,memiii   tempy ",memiii ,tempy )
    print(" ")
    heremin_y=tempy
    memdelta2 =heremin_y

    linestart=0
    nextlinestart=0
    lines=0
    hereindex=0
    while hereindex<success_bph:
        #这个y 接近的 各个点 ，组成 一行line， 保存，也得到nextlinestart
        for iii in range(0, (success_bph)):
            #print("iii",iii)
            delta=mycache_x_y_v_LF[iii][1]-tempy
            if delta<(bph_height/2) and delta>=0:
                #print("iii-hereindex",hereindex)
                mycache_iiiiii[hereindex] = iii
                hereindex+=1
                print(iii)
        print("okok",bph_height/2)
        nextlinestart= hereindex
        linestartmem[lines]=linestart
        nextlinestartmem[lines]=nextlinestart


        #line  ,x 排序
        print ("linestart, nextlinestart",linestart,nextlinestart)
        for jjj in range(linestart, nextlinestart):
            #print(jjj,"jjj")
            for jj in range(linestart, nextlinestart-1):
                #print("jj",jj)
                if  mycache_x_y_v_LF[mycache_iiiiii[jj]][0] >mycache_x_y_v_LF[mycache_iiiiii[jj+1]][0]:
                    hi=mycache_iiiiii[jj]
                    mycache_iiiiii[jj]=mycache_iiiiii[jj+1]
                    mycache_iiiiii[jj+1]=hi


        for jjj in range(linestart, nextlinestart ):
            print("x=", mycache_x_y_v_LF[mycache_iiiiii[jjj]][0],"y=", mycache_x_y_v_LF[mycache_iiiiii[jjj]][1], "v=",mycache_x_y_v_LF[mycache_iiiiii[jjj]][2],"line=",lines)

        linestart = nextlinestart
        lines += 1


        memy=tempy
        memdelta2=10000  #heremax_y
         #得  剩余之 最小 y,赋值给tempy
        for iii in range(0, (success_bph)):
            delta2=  mycache_x_y_v_LF[ iii][1]-memy
            #print("mdelta2",memdelta2,"bph h",bph_height)
            if delta2>(bph_height/2):
                if delta2<memdelta2:
                    memdelta2=delta2
                    memiii=iii
                    tempy = mycache_x_y_v_LF[ iii][1]
        bhp_height = mycache_BPHheight[memiii]
        print("memiii   tempy(min y for this time) ", memiii, tempy)

    # redo,get mycache_v mycache_LF ,again
    for ij in  range(0, (success_bph)):
        mycache_v[ij]= mycache_x_y_v_LF[mycache_iiiiii[ij]][2]
        mycache_LF[ij]=mycache_x_y_v_LF[mycache_iiiiii[ij]][3]
    #测试打印
    print(" ")
    print("bph count:",success_bph ,",lines count:",lines)
    print("after sort，mycache_v", mycache_v, "mycache_LF", mycache_LF)

     ## for return !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    myba_hex_str=""
    myLF_hex_str=""
    l = [hex(int(i)) for i in mycache_v]
    myba_hex_str=" ".join(l)
    ll=[hex(int(i)) for i in mycache_LF]
    myLF_hex_str = " ".join(ll)
    print(  "mycache_v HEX:," ," ".join(l))
    print("mycache_LF HEX:,", " ".join(ll))

    #`o substitute :
    substitutestring=bytearray([0x30]*(success_bph*2))
    someb=b'0'
    someb2=b'0'
    someb3=b'0'
    for ijk in range(0,success_bph):
        someb= mycache_v[ijk]
        someb2=(someb & 15)
        someb2=someb2 |96
        someb3=(someb>>4)
        someb3 = someb3 | 96
        substitutestring[ijk*2] =someb3
        substitutestring[ijk * 2+1] = someb2
    print(" `o_substitutestring:",substitutestring.decode())
    print("show string ##############################################")
    str1 = ['0'] * (success_bph)
    for ii in range(0, success_bph):
        str1[ii] = chr(mycache_v[ii])
    str11 = ''.join('%s' % id for id in str1)
    print(str11)
    #
    print("show bytearray ##############################################")
    myba=bytearray([0x30]*success_bph)
    myba=bytearray(mycache_v)
    print("myba",myba)

    # draw,   mark mark mark mark mark mark mark mark mark mark mark mark mark mark mark mark mark mark

    location_str=""

    for iii in range(0, (success_bph)):
        drawx = mycache_x_y_v_LF[iii][0]
        drawy = mycache_x_y_v_LF[iii][1]
        ##for return !!!!!!!!!!!!!!!!!!!!!!!!
        location_str+=int_to_str(drawx)+" "+int_to_str(drawy)+";"

        htstr=hex(mycache_x_y_v_LF[iii][2]) # 类似  0xEF 的 样子 ，0xf 0xf0 0x0 0xff，
        if len(htstr)==3:
            htstr='0'+htstr[2:3]
            htstr=htstr.upper()
        else:
            htstr = htstr[2:4].upper()
        drawstr=htstr

        # 起点和终点的坐标
        ptStart = (drawx, drawy)
        ptEnd = (drawx + 10, drawy + 10)
        point_color = (0, 255, 0)  # BGR
        thickness = 1
        lineType = 4
        # cv2.line(imageRGB, ptStart, ptEnd, point_color, thickness, lineType)

        # 十六进制串  在图片添加文字，参数为，图片，绘制文字，位置，字体类型，字体大小，颜色，线条类型
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(imageRGB, drawstr, (drawx, drawy), font, 1, (0, 0, 127), 1)
        if mycache_x_y_v_LF[iii][3]==2:
            cv2.putText(imageRGB, drawstr, (drawx+5, drawy+5), font, 1, (0, 0, 127), 1)
        # char  ascii
        hb = bytearray([0] * 1)
        hb[0] = mycache_x_y_v_LF[iii][2]
        drawchr_ascii = hb.decode("ASCII", 'ignore')
        cv2.putText(imageRGB, drawchr_ascii, (drawx, drawy + 20), font, 1, (0, 127, 0), 1)

    #cv2.imshow("original,HEX chr pair,ASCII chr, "+picfilename, imageRGB)
    cv2.imshow("original,HEX chr pair,ASCII chr, " , imageRGB)
    #markedImg=imageRGB

    print("show all string  ##############################################")
    print("as ASCII charcode,print:")  # 'gb2312' 'gbk'  'utf-8' 'utf-16'
    myba2str = myba.decode("ASCII", 'replace')#'ignore')
    print(myba2str)
    print(" ")

    print("as utf_8 charcode,print:")
    #for return!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    suppose_str_utf_8=""
    myba2str=myba.decode("UTF-8",'replace')#'ignore')
    suppose_str_utf_8= myba2str
    print(myba2str)
    print(" ")
    #tkinter.messagebox.showinfo(str(success_bph)+',as utf-8,', myba2str)

    print("as GBK charcode,print:")  # 'gb2312' 'gbk'  'utf-8' 'utf-16'
    myba2str = myba.decode('GBK','replace')#'ignore')
    print(myba2str)
    print(" ")
    #tkinter.messagebox.showinfo('提示,as GBK,', myba2str)

    print("as unicode LE charcode,print:")  # 'gb2312' 'gbk'  'utf-8' 'utf-16'
    myba2str = myba.decode('utf_16_le', 'replace')#'ignore')  # 'ignore'   'strict'  'replace' 'xmlcharrefreplace'
    print(myba2str)
    print(" ")

    print("as unicode BE charcode,print:")  # 'gb2312' 'gbk'  'utf-8' 'utf-16'
    myba2str = myba.decode('utf_16_be','replace')# 'ignore')  # 'ignore'   'strict'  'replace' 'xmlcharrefreplace'
    print(myba2str)




    print("show  in lines @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ")

    linestr=['0123']*lines
    for kk in range(0, lines):
        str1 = ['0'] * (nextlinestartmem[kk] - linestartmem[kk])
        myba2 = bytearray([0x30] * (nextlinestartmem[kk] - linestartmem[kk]))
        tempindex = 0
        for ii in range(linestartmem[kk], nextlinestartmem[kk]):
            myba2[tempindex] = mycache_v[ii]
            tempindex += 1
            # myba.append(mycache_v[ii])

        linestr[kk] = myba2.decode("ASCII", 'ignore')
        print("linestr as ASCII ", linestr[kk])

    for kk in range(0, lines):
        myba2 = bytearray([0x30] * (nextlinestartmem[kk] - linestartmem[kk]))
        tempindex = 0
        for ii in range(linestartmem[kk], nextlinestartmem[kk]):
            myba2[tempindex] = mycache_v[ii]
            tempindex += 1
        linestr[kk] = myba2.decode("GBK", 'replace')#'strict')#'ignore')
        print("linestr as GBK ", linestr[kk])
    hstr = ''
    for kk in range(0, lines):
        hstr = hstr + linestr[kk] + '''\n'''
    if showDialog=="dialog":
        tkinter.messagebox.showinfo(str(success_bph) + ',as GBK,', hstr)



    for kk in range(0, lines):
        myba2 = bytearray([0x30] * (nextlinestartmem[kk] - linestartmem[kk]))
        tempindex = 0
        for ii in range(linestartmem[kk], nextlinestartmem[kk]):
            myba2[tempindex] = mycache_v[ii]
            tempindex += 1
        linestr[kk] = myba2.decode("UTF_8", 'replace')#'strict')#'ignore')
        print("linestr as UTF_8 ", linestr[kk])
    hstr=''
    for kk in range(0, lines):
        hstr=hstr+linestr[kk]+'''\n'''
    if showDialog == "dialog":
        tkinter.messagebox.showinfo(str(success_bph) + ',as utf-8,', hstr)

    for kk in range(0, lines):
        myba2 = bytearray([0x30] * (nextlinestartmem[kk] - linestartmem[kk]))
        tempindex = 0
        for ii in range(linestartmem[kk], nextlinestartmem[kk]):
            myba2[tempindex] = mycache_v[ii]
            tempindex += 1
        linestr[kk] = myba2.decode("UTF_16_LE", 'replace')# 'ignore')
        print("linestr as UTF_16_LE ", linestr[kk])


    for kk in range(0, lines):
        myba2 = bytearray([0x30] * (nextlinestartmem[kk] - linestartmem[kk]))
        tempindex = 0
        for ii in range(linestartmem[kk], nextlinestartmem[kk]):
            myba2[tempindex] = mycache_v[ii]
            tempindex += 1
        linestr[kk] = myba2.decode("UTF_16_BE",  'replace')#'ignore')
        print("linestr as UTF_16_BE", linestr[kk])

    print(resizecode+"  ok!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
    myall = str(success_bph)+"|"+"imagesize_w_h "+str(sp[1])+" "+str(sp[0])+"|"+location_str+"|" +myba_hex_str+"|"+myLF_hex_str+"|"+suppose_str_utf_8
    print(myall)
    print(" ")
    print(" ")
    print(" ")
   # root=tkinter.Tk()
    #root.withdraw()#隐藏
    #root.update()#隐藏
    #root.visible=0
    #txt=tkinter.messagebox.askyesno(success_bph,"ok?")
    #root.destroy()
    #cv2.waitKey(55000)

    #cv2.destroyAllWindows()   #s39
    print("all pictures  clear , !!!!!!!!!!!!!!!!!!!!!!!!!!!!!, u can input # upon line , so not clear ,u  can see detail!     search #s39 ,...")
    return success_bph,"imagesize_w_h "+str(sp[1])+" "+str(sp[0]),location_str, myba_hex_str,myLF_hex_str,suppose_str_utf_8,imageRGB#markedImg

# socket


if __name__ == "__main__":

    #top = tkinter.Tk()
    #top.geometry('0x0+999999+0')
    ##res = tkinter.messagebox.askyesno("提示", "要执行此操作？")
    #tkinter.messagebox.showinfo('提示', " ")
    #top.destroy()


    ######################     capture
    cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)  #if  not 0  ,you can try 700
    print("capture初始化成功！")

    #savedpath = r'd:\\py\\'
    savedpath = os.getcwd()+'\\'
    print(savedpath )
    isExists = os.path.exists(savedpath)
    if not isExists:
        os.makedirs(savedpath)
        print('path of %s is build' % (savedpath))
    else:
        print('path of %s already exist and rebuild' % (savedpath))
    ret, frame = cap.read()

    cameraFound=True
    shoot = True
    if ret==False:
        shoot=False
        cameraFound =False
        print("camera 0  or 700 not found")

    herecnt=1000#30 10  #  delay 10 seconds,to form video, then , snap pic
    cv2.namedWindow("Image")
    while (shoot):
        ret, frame = cap.read()      #拍照
        cv2.waitKey(200)             #延时200毫秒

         # Python监听鼠标键盘事件   https://www.cnblogs.com/cmm2016/p/6775409.html
        # ord 得到整数
        #print(cv2.waitKey(100))
        if cv2.waitKey(100)&0xFF==0x0D:  # (Key.esc):   #  ==ord('s'):     # 'F1': 0x70 ????  , #'left_arrow': 0x25   ???, # 'page_up': 0x21 ????, #'enter': 0x0D OKOKOK,# 'tab': 0x09 OKOKOK,  #'home': 0x24???, 'spacebar': 0x20 OKOKOK,
            sys.exit() #退出程序
        if cv2.waitKey(100)&0xFF==ord('\x1b'):   #(Key.esc):   #('s'):
            shoot = False
        herecnt=herecnt-1
        if herecnt==0:
            shoot=False
        if shoot==True:
            font = cv2.FONT_HERSHEY_SIMPLEX
            cv2.putText(frame, str(herecnt) + "press keyboard  Esc to snap,   ", (10, 60), font, 1, (0, 0, 127), 1)
            cv2.putText(frame, "select file  OK      for BPHor", (10, 100), font, 1,  (0, 0, 127), 1)
            cv2.putText(frame, "select file  cancel  for snap again", (10, 160), font, 1, (0, 0, 127), 1)
            cv2.imshow(" press Esc , snap, filename is   camera_snap.jpg       press Enter to exit", frame)

    savedname = 'camera_snap' + '.jpg'                      #默认文件名
    if cameraFound ==True:
        cv2.imwrite(savedpath + savedname, frame)            #存盘
    cap.release()
    cv2.destroyAllWindows()
    ############      end capture




    #############################
    #socket
    ##def socket_service():


    #################### #  end  socket

    BPHlast=1111
    mylocation_str=""
    while 1==1:

        root = tkinter.Tk()
        root.withdraw()  # 隐藏 hide that little blank dialog
        root.update()  # 隐藏
        # 对话。
        print(" start select a filename:  ")
        picfilename = tkinter.filedialog.askopenfilename(initialdir=os.getcwd())  #选文件名
        print(" so:::::::::" + picfilename)

        if cameraFound==False and   picfilename=="":   #摄像头 未用，  对话选文件名 是 空， 就退出程序。
            sys.exit()  # 退出程序

        while picfilename=="":
            ######################     capture
            cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)  # if  not 0  ,you can try 700
            print("capture初始化成功！")

            # savedpath = r'd:\\py\\'
            savedpath = os.getcwd() + '\\'
            print(savedpath)
            isExists = os.path.exists(savedpath)
            if not isExists:
                os.makedirs(savedpath)
                print('path of %s is build' % (savedpath))
            else:
                print('path of %s already exist and rebuild' % (savedpath))
            ret, frame = cap.read()

            cameraFound = True
            shoot = True
            if ret == False:
                shoot = False
                cameraFound =False
                print("camera 0  or 700 not found")

            herecnt = 100  # 30  #  delay 10 seconds,to form video, then , snap pic
            cv2.namedWindow("Image")
            while (shoot):
                ret, frame = cap.read()

                cv2.waitKey(200)
                if cv2.waitKey( 100) & 0xFF == 0x0D:  # (Key.esc):   #  ==ord('s'):     # 'F1': 0x70 ????  , #'left_arrow': 0x25   ???, # 'page_up': 0x21 ????, #'enter': 0x0D OKOKOK,# 'tab': 0x09 OKOKOK,  #'home': 0x24???, 'spacebar': 0x20 OKOKOK,
                    sys.exit() #退出程序
                if cv2.waitKey(100) & 0xFF == ord('\x1b'):#('s'):
                    shoot = False
                herecnt = herecnt - 1
                if herecnt == 0:
                    shoot = False
                if shoot == True:
                    font = cv2.FONT_HERSHEY_SIMPLEX
                    cv2.putText(frame, str(herecnt) + " press keyboard  Esc to snap   ", (60, 60), font, 1, (0, 0, 127), 1)
                    cv2.putText(frame, "select file ,  OK      for BPHor", (10, 100), font, 1, (0, 0, 127), 1)
                    cv2.putText(frame, "select file ,  cancel  for snap again", (10, 160), font, 1, (0, 0, 127), 1)

                    # 编码转换不起作用啊 ？？？由于在OpenCV-Python包中，imshow函数的窗口标题是gbk编码，而Python3默认UTF-8编码。因而窗口标题包含中文时，会显示乱码。 要 转换  啊 ！！！.encode("gbk").decode(errors="ignore")
                    cv2.imshow("now ,press Esc , snap,   filename is   camera_snap.jpg     press Enter to exit", frame)   # 按 Esc键 拍照， 然后： 若 选文件 ok，识别之；若 不选文件Cancel,继续拍照

            savedname = 'camera_snap' + '.jpg'                      #默认文件名   #    'example' + '.jpg'
            if cameraFound == True:
                cv2.imwrite(savedpath + savedname, frame)
            cap.release()
            cv2.destroyAllWindows()
            ############      end capture

            root = tkinter.Tk()
            root.withdraw()  # 隐藏
            root.update()  # 隐藏
            # 对话
            print(" start select a filename:  " )
            picfilename = tkinter.filedialog.askopenfilename(initialdir=os.getcwd())
            print(" :::::::::"+picfilename)
        cv2.destroyAllWindows()
        #imageRGB = cv2.imread(picfilename)  #读图片文件     这个 文件名带汉字， 会 程序退出 报错！！！！
        imageRGB = cv2.imdecode(np.fromfile(picfilename,dtype=np.uint8),-1)  # 读图片文件   这个 文件名带汉字可以

        BPHlast,size_w_h,mylocation_str ,x_return,y_return,str_return,markedImg= main("normal", imageRGB,"nodialog")
        cv2.imshow('markedImg'+y_return+str_return, markedImg)
        ##cv2.waitKey(0)
        print("")
        print("size_W_H",size_w_h)
        print("location_str",mylocation_str)
        print("x_return",x_return)
        print("y_return",y_return)
        print("str_return",str_return)
        if BPHlast<1:#   <=1  BPH检测得 太少， 增一次 放大后检测。

            # imageRGB = cv2.imread(picfilename)  #读图片文件     这个 文件名带汉字， 会 程序退出 报错！！！！
            imageRGB = cv2.imdecode(np.fromfile(picfilename, dtype=np.uint8), -1)  # 读图片文件   这个 文件名带汉字可以

            BPHlast,size_w_h,mylocation_str,x_return,y_return,str_return,markedImg=main("resize_again",imageRGB,"nodialog")
            cv2.imshow('markedImg resize again '+y_return+str_return, markedImg)
        ##cv2.waitKey(0)

        messagebox.showinfo("提示", "LF="+y_return+"\n"+"HEX:"+x_return+"\n"+str_return)
